//
//  AVPlayerManagem.swift
//  ios_swift_demo1
//
//  Created by liutao on 2020/7/17.
//  Copyright © 2020 lt. All rights reserved.
//


import UIKit
import AVFoundation
import RxSwift
import RxCocoa



private let STATUS_KEYPATH = "status"
private var PlayerItemStatusContent: Void?

protocol DYPlayerViewDelegate: AnyObject {
    func onItemStatusChange(status: AVPlayerItem.Status)
    
    func onItemCurrentTimeChange(current: Float64, duration: Float64)
}

class DYPlayerView: UIView {
    var viewModel: VideoCellViewModel?
    
    private var playerItem: AVPlayerItem!
    
    private var player: AVPlayer!
    
    private var playProgressView:UIProgressView!
    
    private var lastTapTime:TimeInterval = 0
    private var lastTapPoint:CGPoint = .zero
    private var timer:Timer!
    
    var videoGravity: AVLayerVideoGravity {
        set {
            playerLayer.videoGravity = newValue
        }
        get {
            return playerLayer.videoGravity
        }
    }
    
    var assetUrl: URL? {
        didSet {
            prepareToPlay()
        }
    }
    
    //重复播放
    var shouldAutorepeat: Bool = true
    weak var delegate: DYPlayerViewDelegate?
    
    private var timeObserverToken: Any?
    private var playToEndObserverToken: NSObjectProtocol?
    
    override class var layerClass: AnyClass {
        return AVPlayerLayer.self
    }

    private var playerLayer: AVPlayerLayer {
        return layer as! AVPlayerLayer
    }
    
    init(assetUrl: URL) {
        self.assetUrl = assetUrl
        super.init(frame: CGRect.zero)
        backgroundColor = UIColor.black
        autoresizingMask = [.flexibleHeight, .flexibleWidth]
        prepareToPlay()
    }
    
    init() {
        super.init(frame: CGRect.zero)
        backgroundColor = UIColor.black
        autoresizingMask = [.flexibleHeight, .flexibleWidth]
        addPlayProgressView()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //MARK:准备播放
    func prepareToPlay() {
        guard let assetUrl = assetUrl else { return }
        playerItem = AVPlayerItem(url: assetUrl)
        if let player = player {
            DYPlayerManager.shared.remove(owner: self.viewController() ?? self, player: player)
        }
        player = AVPlayer(playerItem: playerItem)
        playerLayer.player = player
        playerItem.addObserver(self, forKeyPath: STATUS_KEYPATH, options: .new, context: &PlayerItemStatusContent) //获取播放的状态
        addTapControlGesture()
        print("DYPlayerView-->准备播放")
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        DispatchQueue.main.async {
            guard let playerItem = self.playerItem, context == &PlayerItemStatusContent else { return }
            playerItem.removeObserver(self, forKeyPath: STATUS_KEYPATH)
            self.addPlayerTimeObserver()
            self.addPlayerItemEndObserver()
            
            self.delegate?.onItemStatusChange(status: playerItem.status)
        }
    }
    
    private func addPlayerTimeObserver() {
    
        let interval = CMTimeMakeWithSeconds(1, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
        timeObserverToken = self.player.addPeriodicTimeObserver(forInterval: interval, queue: DispatchQueue.main) { [weak self] (time) in
            let currentTime = CMTimeGetSeconds(time)
            guard let itemDuration = self?.playerItem.duration else { return }
            let duration = CMTimeGetSeconds(itemDuration)
//            print("DYPlayerView-->addPlayerTimeObserver\(currentTime)--->\(duration)")
            self?.playProgressView.setProgress(Float(currentTime/duration), animated: true)
        }
    }
    
    private func addPlayerItemEndObserver() {
        if let playToEndObserverToken = playToEndObserverToken {
            NotificationCenter.default.removeObserver(playToEndObserverToken)
        }
        
        playToEndObserverToken = NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.playerItem,
                                               queue: OperationQueue.main) { [weak self] _ in
                                                self?.player.seek(to: CMTime.zero, completionHandler: {
                                                    if $0, self?.shouldAutorepeat ?? false {
                                                        self?.player.play()
                                                    }
                                                }) }
    }
    
    private func addTapControlGesture() {
        let tap = UITapGestureRecognizer(target: self, action: #selector(tapGestureEvent(gesture:)))
        self.addGestureRecognizer(tap)
    }
    
    @objc private func tapGestureEvent(gesture: UITapGestureRecognizer) {

        
        //获取点击坐标，用于设置爱心显示位置
        let point = gesture.location(in: self)
        //获取当前时间
        let time = CACurrentMediaTime()
        //判断当前点击时间与上次点击时间的时间间隔
        if(time - lastTapTime)>0.25{
             self.perform(#selector(singleTapAction), with: nil, afterDelay: 0.25)
        }else{
            //取消执行单击方法
            NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(singleTapAction), object: nil)
            
            
            //执行连击显示爱心的方法
            showLikeViewAnim(newPoint: point, oldPoint: lastTapPoint)
//            ZanAnimation.showAnimation(point: point, baseView: self)
            
            NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(postLike), object: nil)
            self.perform(#selector(postLike), with: nil, afterDelay: 0.25)
        }
        //更新上一次点击位置
        lastTapPoint = point
        //更新上一次点击时间
        lastTapTime = time
    }
        
    @objc func postLike(){
        viewModel?.doubleClickLikedStatus()
    }
    
    //单机方法
   @objc func singleTapAction(){
        //当前暂停状态
        if player.rate == 0 {
            play()
            viewModel?.status.accept(.playing)
        } else if (player?.rate ?? 0) > 0 {
            pause()
            viewModel?.status.accept(.pause)
        }
    }
    
    public func play() {
        DYPlayerManager.shared.play(owner: self.viewController() ?? self, player: player)
    }
    
    public func pause() {
        DYPlayerManager.shared.pasueAll()
    }
    
    func addPlayProgressView() {
           playProgressView = UIProgressView(progressViewStyle: .default)
           playProgressView.trackTintColor = UIColor.clear
           playProgressView.progressTintColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
           playProgressView.alpha = 1
           playProgressView.transform = CGAffineTransform(scaleX: 1.0, y: 2.0) //改变
           self.addSubview(playProgressView)
       playProgressView.setProgress(0, animated: true)
           playProgressView.translatesAutoresizingMaskIntoConstraints = false
           playProgressView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
           if #available(iOS 11.0, *) {
               playProgressView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor).isActive = true
           } else {
                 playProgressView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
           }
           playProgressView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
           playProgressView.heightAnchor.constraint(equalToConstant: 1).isActive = true
       }
    
    
    func showLikeViewAnim(newPoint:CGPoint, oldPoint:CGPoint) {
        let likeImageView = UIImageView.init(image: UIImage.init(named: "icon_like_btn_S"))
        var k = (oldPoint.y - newPoint.y) / (oldPoint.x - newPoint.x)
        k = abs(k) < 0.5 ? k : (k > 0 ? 0.5 : -0.5)
        let angle = .pi/4 * -k
        likeImageView.frame = CGRect.init(origin: newPoint, size: CGSize.init(width: 80, height: 80))
        likeImageView.transform = CGAffineTransform.init(scaleX: 0.8, y: 1.8).concatenating(CGAffineTransform.init(rotationAngle: angle))
        self.addSubview(likeImageView)
        UIView.animate(withDuration: 0.2, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 1.0, options: .curveEaseOut, animations: {
            likeImageView.transform = CGAffineTransform.init(scaleX: 1.0, y: 1.0).concatenating(CGAffineTransform.init(rotationAngle: angle))
        }) { finished in
            UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseOut, animations: {
                likeImageView.transform = CGAffineTransform.init(scaleX: 3.0, y: 3.0).concatenating(CGAffineTransform.init(rotationAngle: angle))
                likeImageView.alpha = 0.0
            }, completion: { finished in
                likeImageView.removeFromSuperview()
            })
        }
    }
    
    //页面销毁
    deinit {
        print("DYPlayerView销毁")
        DYPlayerManager.shared.pause(player: player)
        DYPlayerManager.shared.remove(owner: self.viewController() ?? self)
        self.playProgressView.removeSubviews()
        if let playToEndObserverToken = playToEndObserverToken {
            NotificationCenter.default.removeObserver(playToEndObserverToken, name: .AVPlayerItemDidPlayToEndTime, object: self.playerItem)
            self.playToEndObserverToken = nil
        }
    }
}


extension Reactive where Base: DYPlayerView {
    var playUrl: Binder<URL?> {
        return Binder(base) { playerView, url in
            playerView.assetUrl = url
        }
    }
}
